package tech.edwardvan.java.generic;

import lombok.Data;

/**
 * 泛型类
 * <p>
 * 类型擦除
 * Java中的泛型是在编译器这个层次来实现的
 * 在生成的Java字节代码中是不包含泛型中的类型信息的
 * 使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉,这个过程就称为类型擦除
 * 比如并不存在List<String>.class或是List<Integer>.class,而只有List.class
 * 类型擦除的基本过程也比较简单,首先是找到用来替换类型参数的具体类
 * 这个具体类一般是Object,如果指定了类型参数的上界的话,则使用这个上界
 *
 * @author EdwardVan
 */
@Data
public class GenericClassDemo {

    public static void main(String[] args) {
        //继承时不指定泛型
        ContainerChild1 c1 = new ContainerChild1();
        c1.setT("test");
        c1.setT(1);

        //继承时指定泛型
        ContainerChild2 c2 = new ContainerChild2();
        c2.setT("test");
        //c2.setT(1);//error

        //继承泛型
        ContainerChild3<Integer> c3 = new ContainerChild3<>();
        //c3.setT("test");//error
        c3.setT(1);
    }

    /**
     * 泛型类
     */
    @Data
    public static class GenericClass<T> {
        private T t;
    }

    /**
     * 继承时不指定泛型
     */
    public static class ContainerChild1 extends GenericClass {
    }

    /**
     * 继承时指定泛型
     */
    public static class ContainerChild2 extends GenericClass<String> {
    }

    /**
     * 继承泛型
     */
    public static class ContainerChild3<T> extends GenericClass<T> {
    }
}
